home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /* Tom Davis -- 1992 */
-
- #include <math.h>
- #include <stdio.h>
-
- #define STACKDEPTH 10
-
- typedef struct {
- float mat[4][4];
- float norm[3][3];
- } mat_t;
-
- static mat_t matstack[STACKDEPTH] = {
- {{{1.0, 0.0, 0.0, 0.0},
- {0.0, 1.0, 0.0, 0.0},
- {0.0, 0.0, 1.0, 0.0},
- {0.0, 0.0, 0.0, 1.0}},
- {{1.0, 0.0, 0.0},
- {0.0, 1.0, 0.0},
- {0.0, 0.0, 1.0}}},
- };
- static long identitymat = 1;
-
- static long mattop = 0;
-
- void m_resetmatrixstack()
- {
- long i, j;
-
- mattop = 0;
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- matstack[0].mat[i][j] = (i == j) ? 1.0 : 0.0;
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- matstack[0].norm[i][j] = (i == j) ? 1.0 : 0.0;
- identitymat = 1;
- }
-
- void m_xformpt(float pin[3], float pout[3], float nin[3], float nout[3])
- {
- long i;
- float ptemp[3], ntemp[3];
- mat_t *m = &matstack[mattop];
-
- if (identitymat) {
- for (i = 0; i < 3; i++) {
- pout[i] = pin[i];
- nout[i] = nin[i];
- }
- return;
- }
- for (i = 0; i < 3; i++) {
- ptemp[i] = pin[0]*m->mat[0][i] +
- pin[1]*m->mat[1][i] +
- pin[2]*m->mat[2][i] +
- m->mat[3][i];
- ntemp[i] = nin[0]*m->norm[0][i] +
- nin[1]*m->norm[1][i] +
- nin[2]*m->norm[2][i];
- }
- for (i = 0; i < 3; i++) {
- pout[i] = ptemp[i];
- nout[i] = ntemp[i];
- }
- normalize(nout);
- }
-
- void m_xformptonly(float pin[3], float pout[3])
- {
- long i;
- float ptemp[3];
- mat_t *m = &matstack[mattop];
-
- if (identitymat) {
- for (i = 0; i < 3; i++) {
- pout[i] = pin[i];
- }
- return;
- }
- for (i = 0; i < 3; i++) {
- ptemp[i] = pin[0]*m->mat[0][i] +
- pin[1]*m->mat[1][i] +
- pin[2]*m->mat[2][i] +
- m->mat[3][i];
- }
- for (i = 0; i < 3; i++) {
- pout[i] = ptemp[i];
- }
- }
-
- void m_pushmatrix()
- {
- if (mattop < STACKDEPTH-1) {
- matstack[mattop+1] = matstack[mattop];
- mattop++;
- } else
- error("m_pushmatrix: stack overflow\n");
- }
-
- void m_popmatrix()
- {
- if (mattop > 0)
- mattop--;
- else
- error("m_popmatrix: stack underflow\n");
- }
-
- void m_shear(float xy, float xz, float yz)
- {
- long i;
- mat_t *m = &matstack[mattop];
- float temp[4][4];
-
- identitymat = 0;
- for (i = 0; i < 4; i++) {
- temp[0][i] = m->mat[0][i] + xy*m->mat[1][i] + xz*m->mat[2][i];
- temp[1][i] = m->mat[1][i] + yz*m->mat[2][i];
- }
- for (i = 0; i < 4; i++) {
- m->mat[0][i] = temp[0][i];
- m->mat[1][i] = temp[1][i];
- }
- for (i = 0; i < 3; i++) {
- temp[1][i] = -xy*m->norm[0][i] + m->norm[1][i];
- temp[2][i] = (xy*yz-xz)*m->norm[0][i] - yz*m->norm[1][i] + m->norm[2][i];
- }
- for (i = 0; i < 3; i++) {
- m->norm[1][i] = temp[1][i];
- m->norm[2][i] = temp[2][i];
- }
- }
-
- void m_translate(float x, float y, float z)
- {
- long i;
- mat_t *m = &matstack[mattop];
-
- identitymat = 0;
- for (i = 0; i < 4; i++)
- m->mat[3][i] = x*m->mat[0][i] +
- y*m->mat[1][i] +
- z*m->mat[2][i] +
- m->mat[3][i];
- }
-
- void m_scale(float x, float y, float z)
- {
- long i;
- mat_t *m = &matstack[mattop];
-
- identitymat = 0;
- for (i = 0; i < 3; i++) {
- m->mat[0][i] *= x;
- m->mat[1][i] *= y;
- m->mat[2][i] *= z;
- }
- for (i = 0; i < 3; i++) {
- m->norm[0][i] /= x;
- m->norm[1][i] /= y;
- m->norm[2][i] /= z;
- }
- }
-
- void m_rotate(float angle, char axis)
- {
- float s, c, temp[4][4];
- mat_t *m = &matstack[mattop];
- long i;
-
- identitymat = 0;
- s = sin(angle);
- c = cos(angle);
-
- switch(axis) {
- case 'x':
- case 'X':
- for (i = 0; i < 4; i++) {
- temp[1][i] = c*m->mat[1][i] + s*m->mat[2][i];
- temp[2][i] = -s*m->mat[1][i] + c*m->mat[2][i];
- }
- for (i = 0; i < 4; i++) {
- m->mat[1][i] = temp[1][i];
- m->mat[2][i] = temp[2][i];
- }
- for (i = 0; i < 3; i++) {
- temp[1][i] = c*m->norm[1][i] + s*m->norm[2][i];
- temp[2][i] = -s*m->norm[1][i] + c*m->norm[2][i];
- }
- for (i = 0; i < 3; i++) {
- m->norm[1][i] = temp[1][i];
- m->norm[2][i] = temp[2][i];
- }
- break;
- case 'y':
- case 'Y':
- for (i = 0; i < 4; i++) {
- temp[0][i] = c*m->mat[0][i] + -s*m->mat[2][i];
- temp[2][i] = s*m->mat[0][i] + c*m->mat[2][i];
- }
- for (i = 0; i < 4; i++) {
- m->mat[0][i] = temp[0][i];
- m->mat[2][i] = temp[2][i];
- }
- for (i = 0; i < 3; i++) {
- temp[0][i] = c*m->norm[0][i] + -s*m->norm[2][i];
- temp[2][i] = s*m->norm[0][i] + c*m->norm[2][i];
- }
- for (i = 0; i < 3; i++) {
- m->norm[0][i] = temp[0][i];
- m->norm[2][i] = temp[2][i];
- }
- break;
- case 'z':
- case 'Z':
- for (i = 0; i < 4; i++) {
- temp[0][i] = c*m->mat[0][i] + s*m->mat[1][i];
- temp[1][i] = -s*m->mat[0][i] + c*m->mat[1][i];
- }
- for (i = 0; i < 4; i++) {
- m->mat[0][i] = temp[0][i];
- m->mat[1][i] = temp[1][i];
- }
- for (i = 0; i < 3; i++) {
- temp[0][i] = c*m->norm[0][i] + s*m->norm[1][i];
- temp[1][i] = -s*m->norm[0][i] + c*m->norm[1][i];
- }
- for (i = 0; i < 3; i++) {
- m->norm[0][i] = temp[0][i];
- m->norm[1][i] = temp[1][i];
- }
- break;
- default:
- error("m_rotate: bad axis\n");
- break;
- }
- }
-